#pragma once

#include "./thread_pool/thread_pool.hpp"
// #ifndef __MY_THREAD_POOL__
// #define __MY_THREAD_POOL__


// #include <iostream>
// #include <thread>
// #include <memory>
// #include <future>
// #include <vector>
// #include <functional>
// #include <mutex>
// #include <condition_variable>
// #include <atomic>
// #include "./thread_pool/functional.hpp"
// class ThreadPool;
// using ThreadPoolPtr = std::shared_ptr<ThreadPool>;


// class ThreadPool
// {
//     // using Functor = std::function<void()>;
//     using Functor = Functional<void(), 128>;
// public:
//     ThreadPool(int thread_count = 5) : _running(true)
//     {
//         for (int i = 0; i < thread_count; i++)
//         {
//             _threads.emplace_back(&ThreadPool::entry, this);
//         }
//     }

//     ~ThreadPool()
//     {
//         if (_running)
//         {
//             stop();
//         }
//     }

//     template <class Fn, class... Args>
//     auto post(Fn &&func, Args&& ... args) -> std::future<decltype(func(args...))>
//     {
//         // 使用packaged_task封装用户任务
//         using return_type = decltype(func(args...));
//         auto func_tmp = std::bind(std::forward<Fn>(func), std::forward<Args>(args)...);
//         auto pack = std::make_shared<std::packaged_task<return_type()>>(func_tmp);
//         // 获取与用户任务产生关联的future对象
//         std::future<return_type> fu = pack->get_future();
//         // 封装packaged_task对象为可作为元素的可调用对象
//         auto task = [pack]()
//         { (*pack)(); };

//         {
//             // 将封装好的可调用对象放到任务队列中
//             std::unique_lock<std::mutex> ul(_mtx);
//             _tasks.push_back(task);
//             _cond.notify_one();
//         }

//         return fu;
//     }

//     void stop()
//     {
//         _running = false;
//         _cond.notify_all();
//         for (auto &e : _threads)
//         {
//             e.join();
//         }
//     }

// private:
//     void entry()
//     {
//         while (_running)
//         {
//             std::vector<Functor> tmp_tasks;
//             {
//                 std::unique_lock<std::mutex> ul(_mtx);
//                 _cond.wait(ul, [this]()
//                            { return !_tasks.empty() || !_running; });
//                 std::swap(_tasks, tmp_tasks);
//             }

//             for(auto& task : tmp_tasks)
//             {
//                 task();
//             }
//         }
//     }

// private:
//     std::mutex _mtx;
//     std::condition_variable _cond;

//     std::atomic<bool> _running;

//     std::vector<Functor> _tasks;
//     std::vector<std::thread> _threads;
// };

// #endif